/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package easyrgb.frame;

import easyrgb.constance.CConfig;
import easyrgb.constance.Language;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableCellRenderer;
import sun.swing.table.DefaultTableCellHeaderRenderer;

/**
 *
 * @author tandn
 */
public class CCenterPanel extends JPanel
{
    public static final int IMAGE_FIELD_WIDTH = 15;
    private String m_fileType = FILE_TYPES_SUPPORTED[0];
    public static final String[] FILE_TYPES_SUPPORTED =
    {
        "png", "sprite"
    };
    public static final int COLUMN_ID = 0;
    public static final int COLUMN_IMAGE = COLUMN_ID + 1;
    public static final int COLUMN_SPRITE = COLUMN_IMAGE + 1;
    private CTableModel m_tableModel;
    private JTable m_table;
    private JButton m_addButton,
            m_deleteButton,
            m_insertButton,
            m_browseImageButton,
            m_browseSpriteButton,
            m_runButton;
    public static final String FILE_OUTPUT_NAME = "res.easyrgb";
    public static final String FILE_JAVA_NAME = "RESOURCE";
    //
    private DataOutputStream dataBinOutputStream;
    private BufferedWriter fileJavaWriter;

    public CCenterPanel()
    {
        JPanel tabPanelButton,
                commonPanelButton,
                browsePanelButton,
                savePanelButton; //for tabs
        setLayout(new BorderLayout());
        /////////////////TABLE
        m_tableModel = new CTableModel();
        m_tableModel.setColumnNames(new String[]
                {
                    Language.COLUMN_TABLE_INDEX[CConfig.LANGUAGE],
                    Language.COLUMN_TABLE_IMAGE[CConfig.LANGUAGE],
                    Language.COLUMN_TABLE_SPRITE[CConfig.LANGUAGE],
                });

        m_tableModel.setData(new String[][]
                {
                });
        m_tableModel.setColumnNonEditable(new int[]
                {
                    COLUMN_ID
                });
        m_table = new JTable(m_tableModel);
        //m_table.setPreferredScrollableViewportSize(new Dimension(TOTAL_COLUMN_TABS_PALETTE * COLUMN_WIDTH, 0));
        m_table.setPreferredScrollableViewportSize(new Dimension(CConfig.WINDOW_WIDTH, 0));
        m_table.setFillsViewportHeight(true);
        m_table.getTableHeader().setReorderingAllowed(false); //disable drag and drop column
        m_table.getColumnModel().getColumn(COLUMN_ID).setPreferredWidth(30);
        DefaultTableCellRenderer cellRenderer = new DefaultTableCellHeaderRenderer();
        cellRenderer.setHorizontalAlignment(JLabel.CENTER);
        m_table.getColumnModel().getColumn(COLUMN_ID).setCellRenderer(cellRenderer);
        m_table.getColumnModel().getColumn(COLUMN_IMAGE).setPreferredWidth(CConfig.WINDOW_WIDTH >> 1);
        m_table.getColumnModel().getColumn(COLUMN_SPRITE).setPreferredWidth((CConfig.WINDOW_WIDTH >> 1) - 30);
        m_table.setRowHeight(20);
//        m_table.setDefaultEditor(String.class, new CStringEditor());
//        m_table.setDefaultRenderer(String.class, new CStringRender());
        add(new JScrollPane(m_table), BorderLayout.CENTER);
        /////////////////BUTTONS
        tabPanelButton = new JPanel(new BorderLayout());
        commonPanelButton = new JPanel();
        savePanelButton = new JPanel();
        browsePanelButton = new JPanel();
        //process the browsing buttons
        m_browseImageButton = new JButton(Language.BROWSE_IMAGE[CConfig.LANGUAGE]);
        m_browseImageButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                int row = m_table.getSelectedRow();
                if (row != -1)
                {
                    m_table.setValueAt(loadImage((String) m_table.getValueAt(row, COLUMN_IMAGE), FILE_TYPES_SUPPORTED[0]), row, COLUMN_IMAGE);
                }
                else
                {
                    JOptionPane.showMessageDialog(CMainWindow.getInstance(), Language.MESSAGE_CHOOSE_CELL_IMAGE[CConfig.LANGUAGE]);
                }
            }
        });
        m_browseSpriteButton = new JButton(Language.BROWSE_SPRITE[CConfig.LANGUAGE]);
        m_browseSpriteButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                int row = m_table.getSelectedRow();
                if (row != -1)
                {
                    m_table.setValueAt(loadImage((String) m_table.getValueAt(row, COLUMN_SPRITE), FILE_TYPES_SUPPORTED[1]), row, COLUMN_SPRITE);
                }
                else
                {
                    JOptionPane.showMessageDialog(CMainWindow.getInstance(), Language.MESSAGE_CHOOSE_CELL_SPRITE[CConfig.LANGUAGE]);
                }
            }
        });
        browsePanelButton.add(m_browseImageButton);
        browsePanelButton.add(m_browseSpriteButton);
        m_browseImageButton.setVisible(false);
        m_browseSpriteButton.setVisible(false);
        tabPanelButton.add(browsePanelButton, BorderLayout.WEST);
        //process the add button
        m_addButton = new JButton(Language.ADD[CConfig.LANGUAGE]);
        m_addButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                m_tableModel.addRow();
                if (m_table.getRowCount() > 0)
                {
                    if (m_table.getRowCount() == 1)
                    {
                        m_table.changeSelection(0, 0, false, false);
                    }
                    m_browseImageButton.setVisible(true);
                    m_browseSpriteButton.setVisible(true);
                }
                m_table.updateUI();
            }
        });
        commonPanelButton.add(m_addButton);
        //process the insert button
        m_insertButton = new JButton(Language.INSERT[CConfig.LANGUAGE]);
        m_insertButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                m_tableModel.insertRow(m_table.getSelectedRow());
                if (m_table.getRowCount() > 0)
                {
                    if (m_table.getRowCount() == 1)
                    {
                        m_table.changeSelection(0, 0, false, false);
                    }
                    m_browseImageButton.setVisible(true);
                    m_browseSpriteButton.setVisible(true);
                }
                m_table.updateUI();
            }
        });
        commonPanelButton.add(m_insertButton);
        //process the delete button
        m_deleteButton = new JButton(Language.DELETE[CConfig.LANGUAGE]);
        m_deleteButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                m_tableModel.deleteRow(m_table.getSelectedRow());
                if (m_table.getRowCount() == 0)
                {
                    m_browseImageButton.setVisible(false);
                    m_browseSpriteButton.setVisible(false);
                }
                m_table.updateUI();
            }
        });
        commonPanelButton.add(m_deleteButton);
        tabPanelButton.add(commonPanelButton, BorderLayout.CENTER);
        //save button
        m_runButton = new JButton(Language.RUN[CConfig.LANGUAGE]);
        m_runButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                processToRGB();
            }
        });
        savePanelButton.add(m_runButton);
        tabPanelButton.add(savePanelButton, BorderLayout.EAST);
        add(tabPanelButton, BorderLayout.SOUTH);
    }

    //<editor-fold defaultstate="collapsed" desc="Function get-set">
    /**
     * @return the m_tableModel
     */
    public CTableModel getTableModel()
    {
        return m_tableModel;
    }

    /**
     * @param m_tableModel the m_tableModel to set
     */
    public void setTableModel(CTableModel m_tableModel)
    {
        this.m_tableModel = m_tableModel;
    }

    /**
     * @return the m_table
     */
    public JTable getTable()
    {
        return m_table;
    }

    /**
     * @param m_table the m_table to set
     */
    public void setTable(JTable m_table)
    {
        this.m_table = m_table;
    }
    //</editor-fold>

    /*
     * process to RGB array and file
     */
    private void processToRGB()
    {
        //temp available
        int[] RGBDatas = null;
        //for sprite data
        File[] spriteArrayFiles;
        //buffer image
        BufferedImage[] bufferedImagesArray;
        //init data storage
        int rowCount = m_table.getRowCount();
        if (rowCount == 0)
        {
            JOptionPane.showMessageDialog(CMainWindow.getInstance(),
                    Language.MESSAGE_NOTHING_TO_DO[CConfig.LANGUAGE]);
            return;
        }
        spriteArrayFiles = new File[rowCount];
        bufferedImagesArray = new BufferedImage[rowCount];
        //file        
        File fileBin = new File(FILE_OUTPUT_NAME);
        File fileJava = new File(FILE_JAVA_NAME + ".java");
        //results
        try
        {
            //create file
            fileBin.createNewFile();
            fileJava.createNewFile();
            //get output stream
            dataBinOutputStream = new DataOutputStream(new FileOutputStream(fileBin));
            fileJavaWriter = new BufferedWriter(new FileWriter(fileJava));
            //write for java file
            fileJavaWriter.write("\n");
            fileJavaWriter.write("public final class " + FILE_JAVA_NAME);
            fileJavaWriter.write("\n{\n");
        } catch (IOException ex)
        {
            Logger.getLogger(CCenterPanel.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }
        //get all data paths from table        
        for (int i = 0; i < rowCount; i++)
        {
            File tempFile = null;
            try
            {
                //get buffer image
                tempFile = new File(((String) m_table.getValueAt(i, COLUMN_IMAGE)).trim());
                Image tempImage = ImageIO.read(tempFile);
                bufferedImagesArray[i] = new BufferedImage(tempImage.getWidth(null), tempImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
                Graphics2D tempGraphics = bufferedImagesArray[i].createGraphics();
                tempGraphics.drawImage(tempImage, null, null);
                //create class java
                String fileName = tempFile.getName().toUpperCase();
                fileName = fileName.substring(0, fileName.length() - 4);
                fileJavaWriter.write("  public static final int " + fileName + "_SPRITE = " + i + ";\n");
                fileJavaWriter.write("  public final class " + fileName + "\n");
                fileJavaWriter.write("  {\n");
                fileJavaWriter.write("      public static final int WIDTH = " + bufferedImagesArray[i].getWidth() + ";\n");
                fileJavaWriter.write("      public static final int HEIGHT = " + bufferedImagesArray[i].getHeight() + ";\n");
            } catch (IOException ex)
            {
                Logger.getLogger(CCenterPanel.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(CMainWindow.getInstance(),
                        Language.MESSAGE_IMAGE_LOAD_FAIL[CConfig.LANGUAGE] + (i + 1) + Language.MESSAGE_IMAGE_PLEASE_CHECK[CConfig.LANGUAGE]);
                return;
            }
            //get data RGB
            RGBDatas = bufferedImagesArray[i].getRGB(0,
                    0,
                    bufferedImagesArray[i].getWidth(),
                    bufferedImagesArray[i].getHeight(),
                    null,
                    0,
                    bufferedImagesArray[i].getWidth());
            //compress array int
            //int temp[] = ..
            //save to file
            if (RGBDatas != null)
            {
                int length = RGBDatas.length;
                try
                {
                    dataBinOutputStream.writeInt(bufferedImagesArray[i].getWidth());//Image width
                    dataBinOutputStream.writeInt(bufferedImagesArray[i].getHeight());//Image height
                    dataBinOutputStream.writeInt(bufferedImagesArray[i].getWidth());//Image scan length
                    for (int j = 0; j < length; j++)
                    {
                        dataBinOutputStream.writeInt(RGBDatas[j]);
                        //dataBinOutputStream.write(intToByteArray(RGBDatas[j]));
                    }
                } catch (Exception e)
                {
                    Logger.getLogger(CCenterPanel.class.getName()).log(Level.SEVERE, null, e);
                }
            }
            //sprite
            spriteArrayFiles[i] = new File(((String) m_table.getValueAt(i, COLUMN_SPRITE)).trim());
            if (spriteArrayFiles[i] == null || spriteArrayFiles[i].length() == 0)
            {
                JOptionPane.showMessageDialog(CMainWindow.getInstance(),
                        Language.MESSAGE_SPRITE_LOAD_FAIL[CConfig.LANGUAGE] + (i + 1) + Language.MESSAGE_SPRITE_PLEASE_CHECK[CConfig.LANGUAGE]);
                return;
            }
            //read the info of module
            Vector<int[]> moduleInfos = loadModuleInfo(spriteArrayFiles[i]);
            int moduleLength = moduleInfos.size();
            try
            {
                dataBinOutputStream.writeInt(moduleLength);//length
                for (int j = 0; j < moduleLength; j++)
                {
                    System.out.println("11111111 "+((moduleInfos.elementAt(j))[0]));//x
                    System.out.println(((moduleInfos.elementAt(j))[1]));//x
                    System.out.println(((moduleInfos.elementAt(j))[2]));//x
                    System.out.println(((moduleInfos.elementAt(j))[3]));//x
                    dataBinOutputStream.writeInt((moduleInfos.elementAt(j))[0]);//x
                    dataBinOutputStream.writeInt((moduleInfos.elementAt(j))[1]);//y
                    dataBinOutputStream.writeInt((moduleInfos.elementAt(j))[2]);//w
                    dataBinOutputStream.writeInt((moduleInfos.elementAt(j))[3]);//h
                }
            } catch (IOException ex)
            {
                //Logger.getLogger(CCenterPanel.class.getName()).log(Level.SEVERE, null, ex);
                ex.printStackTrace();
            }
        }
        //write to Java file and close streams
        try
        {
            fileJavaWriter.write("}\n");
            fileJavaWriter.flush();
            fileJavaWriter.close();
            dataBinOutputStream.flush();
            dataBinOutputStream.close();
        } catch (IOException ex)
        {
            Logger.getLogger(CCenterPanel.class.getName()).log(Level.SEVERE, null, ex);
        }

        //successful
        JOptionPane.showMessageDialog(CMainWindow.getInstance(),
                Language.MESSAGE_SUCCESS[CConfig.LANGUAGE]);
    }

    /*
     * load module info from file sprite
     */
    private Vector<int[]> loadModuleInfo(File spriteFile)
    {
        Vector<int[]> tempArray = new Vector<int[]>();
        try
        {
            BufferedReader reader = new BufferedReader(new InputStreamReader(new DataInputStream(new FileInputStream(spriteFile))));
            String strLine = null;
            while ((strLine = reader.readLine()) != null)
            {
                strLine = strLine.trim();
                //CMainWindow.debug("" + strline);
                if (strLine.startsWith("//"))//do not consider comments
                {
                    continue;
                }
                else if (strLine.startsWith("MD"))
                {
                    int[] intArray = new int[4];
                    String[] strArray = strLine.split("\\s+");
                    //get x y w h
                    int startX = 4;
                    for (int i = 0; i < 4; i++)
                    {
                        intArray[i] = Integer.parseInt(strArray[startX + i]);
                    }
                    tempArray.add(intArray);
                    //write index to java file
                    int lengthStrArray = strArray.length;
                    String indexName = null;
                    for (int i = 8; i < lengthStrArray; i++)
                    {
                        if (i == 8)
                        {
                            if (lengthStrArray == 9)
                            {
                                indexName = strArray[i].substring(1, strArray[i].length() - 1);
                            }
                            else
                            {
                                indexName = strArray[i].substring(1, strArray[i].length());
                                indexName += "_";
                            }
                        }
                        else if (i == lengthStrArray - 1)
                        {
                            indexName += strArray[i].substring(0, strArray[i].length() - 1);
                        }
                        else
                        {
                            indexName += strArray[i];
                        }
                    }
                    if (indexName == null)
                    {
                        fileJavaWriter.write("      public static final int MODULE_" + tempArray.size() + " = " + (tempArray.size() - 1) + ";\n");
                    }
                    else
                    {
                        fileJavaWriter.write("      public static final int " + indexName.toUpperCase() + " = " + (tempArray.size() - 1) + ";\n");
                    }
                }
            }
            fileJavaWriter.write("  }\n");
        } catch (IOException ex)
        {
            Logger.getLogger(CCenterPanel.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return tempArray;
    }

    /*
     * Load image
     */
    private String loadImage(String oldPath, String fileType)
    {
        m_fileType = fileType;
        JFileChooser fileBrowser = new JFileChooser();
        fileBrowser.setFileFilter(new FileFilter()
        {
            @Override
            public boolean accept(File f)
            {
                return f.isDirectory()
                        || f.getName().endsWith(m_fileType);
            }

            @Override
            public String getDescription()
            {
                return Language.IMAGE_DESCRIPTION[CConfig.LANGUAGE]
                        + "(*." + m_fileType
                        + ")";
            }
        });
        int value = fileBrowser.showOpenDialog(CMainWindow.getInstance());
        if (value == JFileChooser.APPROVE_OPTION)
        {
            return fileBrowser.getCurrentDirectory().toString() + "\\" + fileBrowser.getSelectedFile().getName();
        }
        return oldPath;
    }

    public final byte[] intToByteArray(int value)
    {
        return new byte[]
                {
                    (byte) (value >>> 24),
                    (byte) (value >>> 16),
                    (byte) (value >>> 8),
                    (byte) value
                };
    }

    public final int byteArrayToInt(byte[] b)
    {
        return (b[0] << 24)
                + ((b[1] & 0xFF) << 16)
                + ((b[2] & 0xFF) << 8)
                + (b[3] & 0xFF);
    }
}

